package com.sywl.hibernate;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.Query;
import javax.persistence.TypedQuery;

import com.sywl.web.util.SortOrder;

/**
 * 查询缓存
 * 该接口主要用于从二级缓存里面查询对象
 * 此类的所有查询方法都会从二级缓存查询
 * 如果未配置二级环境，将会抛出二级缓存未配置异常
 * 此类用户简化由于配置了二级缓存跟查询缓存，但是当使用EntityManager的createQuery时候
 * 任然会从数据库查询的问题，依旧没有查询缓存
 * 主要解决方式是通过 setHint("org.hibernate.cacheable", true)
 * 达到使用查询缓存的目的
 * @author itachi
 * @see QueryCacheImpl
 */
public interface QueryCache {
	
	/**
	 * 获取实体管理
	 * @return
	 */
	EntityManager getEntityManager();
	
	/**
	 * 根据ID查询指定类型的对象
	 * @param id
	 * @param clazz
	 * @return
	 */
	<T> T find(long id, Class<T> clazz);
	
	/**
	 * 根据给定的查询位置，查询指定类型的对象
	 * @param first
	 * @param maxResult
	 * @param clazz
	 * @return
	 */
	<T> List<T> query(int first, int maxResult, Class<T> clazz);
	
	/**
	 * 查询指定类型的对象
	 * 通过给定的字段跟排序方法进行排序  @See SortOrder
	 * 返回排序后的结果
	 * @param first
	 * @param maxResult
	 * @param sortField
	 * @param clazz
	 * @param sortOrder
	 * @return
	 */
	<T> List<T> queryBySort(int first, int maxResult, String sortField, Class<T> clazz, SortOrder sortOrder);
	
	/**
	 * 查询单个结果
	 * 例如执行count等系列函数
	 * @param sql
	 * @return
	 */
	Object querySingleResult(String sql);
	
	/**
	 * 查询单个结果
	 * 例如执行count等系列函数
	 * @param sql
	 * @return
	 */
	<T> Object querySingleResult(TypedQuery<T> query);
	
	/**
	 * 查询单个结果
	 * 例如执行count等系列函数
	 * @param sql
	 * @return
	 */
	Object querySingleResult(Query query);
	
	/**
	 * 根据给定的查询语句仅需查询
	 * @param sql
	 * @param first
	 * @param maxResult
	 * @param clazz
	 * @return
	 */
	<T> List<T> query(String sql, int first, int maxResult, Class<T> clazz);
	
	/**
	 * 查询制定类的对象总数
	 * @param clazz
	 * @return
	 */
	<T> long count(Class<T> clazz);
	
	/**
	 * 查询制定类的所有对象
	 * @param clazz
	 * @return
	 */
	<T> List<T> findAll(Class<T> clazz);
	
	Query createQuery(String sql);
	
	<T> TypedQuery<T> createQuery(String sql, Class<T> clazz);
	
	<T> TypedQuery<T> createQuery(String sql, int first, int maxResult, Class<T> clazz);
	
	<T> TypedQuery<T> createQuery(TypedQuery<T> query, int first, int maxResult, Class<T> clazz);
	
	<T> List<T> query(TypedQuery<T> query, int first, int maxResult, Class<T> clazz);
	
	<T> T findPrev(Object o);
	
	<T> T findPrev(Object o, String key);
	
	<T> T findNext(Object o);
	
	<T> T findNext(Object o, String key);
	
}
